<template>
	<el-card
		shadow="always"
		:body-style="{ padding: '20px' }"
		style="margin-top: 20px"
	>
		<el-form label-width="100px">
			<el-form-item label="Spu名称">
				<el-input v-model="spuInfo.spuName"></el-input>
			</el-form-item>
			<el-form-item label="品牌">
				<el-select placeholder="请选择" v-model="spuInfo.tmId as number">
					<el-option
						:value="item.id"
						v-for="item in trademarkList"
						:key="item.id"
						:label="item.tmName"
					/>
				</el-select>
			</el-form-item>
			<el-form-item label="Spu描述">
				<el-input
					type="textarea"
					rows="4"
					v-model="spuInfo.description"
				></el-input>
			</el-form-item>
			<el-form-item label="Spu图片">
				<el-upload
					list-type="picture-card"
					action="http://gmall-h5-api.atguigu.cn/admin/product/upload"
					v-model:file-list="imageList"
					:on-remove="handleRemove"
					:on-success="handleAvatarSuccess"
				>
					<el-icon><Plus /></el-icon>
				</el-upload>

				<el-dialog>
					<img w-full alt="Preview Image" />
				</el-dialog>
			</el-form-item>
			<el-form-item label="销售属性">
				<el-select placeholder="请选择销售属性" v-model="spuSaleInfoTemp">
					<el-option
						v-for="item in unUseSaleAttrList"
						:key="item.id"
						:label="item.name"
						:value="`${item.id}:${item.name}`"
					></el-option>
				</el-select>
				<el-button type="primary" @click="addSaleAttr" style="margin-left: 20px"
					>添加销售属性</el-button
				>
				<el-table border stripe style="margin-top: 20px" :data="saleAttrSelf">
					<el-table-column type="index" width="80" label="序号" />
					<el-table-column label="属性名" prop="saleAttrName"></el-table-column>
					<el-table-column label="属性值名称列表">
						<template v-slot="{ row, $index }">
							<el-tag
								style="margin-right: 5px"
								closable
								@close="row.spuSaleAttrValueList.splice($index, 1)"
								v-for="item in row.spuSaleAttrValueList"
								:key="item.id"
								>{{ item.saleAttrValueName }}</el-tag
							>
							<el-button
								v-if="!row.isEdit"
								type="default"
								size="small"
								@click="addAttrValue(row)"
								>新增属性值</el-button
							>
							<el-input
								v-if="row.isEdit"
								placeholder="请新增属性值"
								size="small"
								clearable
								ref="inputEle"
								v-model="inputValue"
								@blur="toLook(row)"
							></el-input>
						</template>
					</el-table-column>
					<el-table-column label="操作">
						<template v-slot="{ row, $index }">
							<el-button
								type="danger"
								size="small"
								@click="saleAttrSelf.splice($index, 1)"
								icon="ele-Delete"
							></el-button>
						</template>
					</el-table-column>
				</el-table>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="save">保存</el-button>
				<el-button @click="emit('changeType', 0)">取消</el-button>
			</el-form-item>
		</el-form>
	</el-card>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import {
	reqAddSpu,
	reqSaleAttrList,
	reqSaleAttrSelf,
	reqSpuImageList,
	reqUpdateSpu,
	type baseSaleAttrListType,
	type SaleAttrItemType,
	type SaleAttrListType,
	type SpuImgListType,
	type SpuInfoType,
} from "@/api/spu";

import { ElMessage, type UploadProps } from "element-plus";
import {
	reqAllTrdeamarkList,
	type AllTrademarkListType,
} from "@/api/trademark";
export default defineComponent({
	name: "SpuForm",
});
</script>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref } from "vue";
import { Plus } from "@element-plus/icons-vue";

// 1. 接收props传的值
const props = defineProps<{
	spuInfo: SpuInfoType;
}>();

// 2. 判断当前是修改或新增 来发送其他的数据请求
// 如果是新增则需要 发送请求1 所有品牌列表  2. 所有销售属性列表
// 如果是修改则需要 发送请求1 所有品牌列表  2. 所有销售属性  3.  根据当前spuId获取销售属性列表  4.  根据当前skuId 获取图片列表

const trademarkList = ref<AllTrademarkListType>([]);
const saleAttrList = ref<baseSaleAttrListType>([]);
const saleAttrSelf = ref<SaleAttrListType>([]);
const imageList = ref<SpuImgListType>([]);

//因为我们将来要对自己的销售属性进行编辑和查看切换,每一条数据上应该保存一个isEdit属性,保存当前的状态
saleAttrSelf.value.forEach(item => {
	item.isEdit = false;
	// 输入框清空
	inputValue.value = "";
});

// 封装获取初始值的方法
const getAllUseData = async () => {
	try {
		if (props.spuInfo.id) {
			// 如果有id 说明是修改
			const r1 = reqAllTrdeamarkList();
			const r2 = reqSaleAttrList();
			const r3 = reqSaleAttrSelf(props.spuInfo.id);
			const r4 = reqSpuImageList(props.spuInfo.id);

			/* 
			Promise.all 方法 可以把所有请求一起发出 若有一个失败 则返回失败
			*/
			const res = await Promise.all([r1, r2, r3, r4]);
			trademarkList.value = res[0];
			saleAttrList.value = res[1];
			saleAttrSelf.value = res[2];
			imageList.value = res[3];

			// 这里注意给imageList添加name和url属性 方便再图片墙上展示  ele自带的是name和url属性
			imageList.value.forEach(item => {
				item.name = item.imgName;
				item.url = item.imgUrl;
			});
		} else {
			// 如果没有 id  那么是新增
			const r1 = reqAllTrdeamarkList();
			const r2 = reqSaleAttrList();
			const res = await Promise.all([r1, r2]);
			trademarkList.value = res[0];
			saleAttrList.value = res[1];
		}
	} catch (error: any) {
		ElMessage.error(error.message);
	}
};

// 获取初始化参数
onMounted(() => {
	getAllUseData();
});

// 定义切换type的自定义事件
const emit = defineEmits<{
	(event: "changeType", newType: number, row?: SpuInfoType): void;
}>();

//删除图片墙的图片回调,现在不需要操作,因为默认和imageList进行双向绑定
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
	// console.log(uploadFile, uploadFiles, imageList);
};

//添加图片墙图片的时候,我们发现imageList也收集了图片,但是格式并不是我们想要的格式,所以我们还是要进行下一步的处理
const handleAvatarSuccess: UploadProps["onSuccess"] = (
	response,
	uploadFile
) => {
	// console.log(response, uploadFile, c);
	// console.log(imageList);
};

// 通过计算属性 计算当前 spu没有使用过的销售属性
const unUseSaleAttrList = computed(() => {
	return saleAttrList.value.filter(item => {
		// 深层次拿到 当前遍历的item和 已经存在的销售属性 一一对比 判断是否存在
		return !saleAttrSelf.value.some(selfItem => {
			// 如果有相等的 则some直接返回true  但是filter要把返回的true过滤 所以取反就可以
			return selfItem.saleAttrName === item.name;
		});
	});
});

// 声明变量 绑定已选择的销售属性
const spuSaleInfoTemp = ref("");
// 点击添加销售属性
const addSaleAttr = () => {
	// 先判断销售属性是否选择
	if (!spuSaleInfoTemp.value) return;
	// 获取销售属性 收集id和name
	const [id, name] = spuSaleInfoTemp.value.split(":"); // 切割字符串

	// 向自己的销售属性列表中 新增销售属性
	saleAttrSelf.value.push({
		baseSaleAttrId: +id, //
		saleAttrName: name,
		spuId: props.spuInfo.id,
		spuSaleAttrValueList: [],
		isEdit: false, // 新增的属性 用来显示input
	});
	// 清空销售属性
	spuSaleInfoTemp.value = "";
};

const inputEle = ref<HTMLInputElement>();

// 点击添加属性值
const addAttrValue = (row: SaleAttrItemType) => {
	row.isEdit = true; // 显示输入框
	// 输入框自动聚焦
	nextTick(() => {
		inputEle.value?.focus();
	});
};

// 创建一个变量 保存添加属性时的input的值
const inputValue = ref("");

// 输入框失焦事件 添加属性值
const toLook = (row: SaleAttrItemType) => {
	row.isEdit = false;

	// 判断输入框的内容是否为空
	if (!inputValue.value.trim()) {
		row.isEdit = false; // 关闭输入框
		ElMessage.error("输入的内容不能为空");
		return;
	}

	// 判断输入内容是否和原来的属性值重复
	const isRepeat = row.spuSaleAttrValueList.some(item => {
		return item.saleAttrValueName === inputValue.value;
	});

	if (isRepeat) {
		ElMessage.error("属性值不能重复添加");
		row.isEdit = false;
		inputValue.value = "";
		return;
	}

	// 添加到属性值
	row.spuSaleAttrValueList.push({
		baseSaleAttrId: row.baseSaleAttrId, // 当前销售属性在基础销售属性列表中的id
		saleAttrName: row.saleAttrName, //销售属性名
		saleAttrValueName: inputValue.value, //销售属性值
		spuId: props.spuInfo.id,
	});

	row.isEdit = false; // 切换到按钮模式
	inputValue.value = ""; //清空输入框
};

// 保存事件
const save = async () => {
	// console.log(props.spuInfo);
	// console.log(saleAttrSelf.value);

	// 1.	处理销售属性列表
	saleAttrSelf.value.forEach(item => {
		delete item.isEdit; // 所有的属性 去掉isEdit属性值
	});

	// 2.处理图片列表
	imageList.value = imageList.value.map(item => {
		// 点击新增图片时 会有response属性  发送请求要求必须有imgName imgUrl这两个属性
		return {
      imgName: item.name as string,
      imgUrl: item.imgUrl || (item.response.data as string),
    };
	});

	// 把整理的数据 交给props.spuInfo
	props.spuInfo.spuSaleAttrList = saleAttrSelf.value;
	props.spuInfo.spuImageList = imageList.value;

	try {
		if (props.spuInfo.id) {
			// 如果有id 那么请求修改接口
			await reqUpdateSpu(props.spuInfo);
			ElMessage.success("修改成功");
		} else {
			await reqAddSpu(props.spuInfo);
			ElMessage.success("新增成功");
		}
		emit('changeType',0)
	} catch (error) {
		ElMessage.error("新增或修改失败");
	}
};
</script>
